import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:cave_flutter/utils/whl_rc_im_utils.dart';
import 'package:cave_flutter/utils/whl_toast_utils.dart';
import 'package:cave_flutter/widgets/whl_bottom_action_sheet.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:nim_core/nim_core.dart';
import 'package:path_provider/path_provider.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import '../brick/brick.dart';
import 'drag_widgets/whl_drag_gesture_detector.dart';

class WhlImageBrowserPage extends StatefulWidget {
  const WhlImageBrowserPage({Key? key, required this.tags, this.messageList, required this.index}) : super(key: key);
  final List<Object> tags;
  final int index;
  final List<NIMMessage>? messageList;

  @override
  State<WhlImageBrowserPage> createState() => _WhlImageBrowserPageState();
}

class _WhlImageBrowserPageState extends State<WhlImageBrowserPage> with SingleTickerProviderStateMixin {
  late int _currentPage;
  late PageController _pageController;
  bool _visible = true;
  bool _isPop = false;
  late AnimationController _controller;
  Animation<Offset>? _animation;
  Offset _offset = Offset.zero;
  double _scale = 1.0;
  Offset? _normalizedOffset;
  double _previousScale = 0;
  double _kMinFlingVelocity = 600.0;
  bool _isEnlarge = false;
  bool _isHideTitleBar = false;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
    _controller.addListener(() {
      setState(() {
        if (_animation != null) {
          _offset = _animation!.value;
        }
      });
    });
    _currentPage = widget.index;
    _pageController = PageController(initialPage: _currentPage);
  }

  @override
  Widget build(BuildContext context) {
    NIMMessage message = widget.messageList![_currentPage];
    Map dic = message.messageAttachment?.toMap()??{};
    String path = dic['path'] ?? '';
    String url = dic['url'] ?? '';
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: Stack(
        children: [
          Center(
            child: WhlDragGestureDetector(
              onPanStart: _onPanStart,
              onPanEnd: _onPanEnd,
              onDoubleTap: () {
                _onDoubleTap(context);
              },
              onScaleStart: (ScaleStartDetails details) {
                _handleOnScaleStart(details);
              },
              onScaleUpdate: (ScaleUpdateDetails details) {
                _handleOnScaleUpdate(details, context);
              },
              onScaleEnd: (ScaleEndDetails details) {
                _handleOnScaleEnd(details, context);
              },
              child: Hero(
                  tag: widget.tags[_currentPage],
                  transitionOnUserGestures: true,
                  child: PageView.builder(
                    controller: _pageController,
                    itemCount: widget.tags.length,
                    itemBuilder: (BuildContext ctx, int index) {
                      NIMMessage model = widget.messageList![index];
                      return GestureDetector(
                        // color: _isHideTitleBar?Colors.black:Colors.white,
                        onLongPress: () {
                          WhlBottomActionSheet.show(['保存至相册'], callBack: (selectedIndex) async {
                            if (selectedIndex == 0) {
                              saveImageToGallery(url);
                            }
                          });
                        },
                        child: SizedBox.expand(
                          child: ClipRect(
                            child: Transform(
                                transform: Matrix4.identity()
                                  ..translate(_offset.dx, _offset.dy)
                                  ..scale(_scale),
                                child: buildImageView(index)),
                            // child: Image.network(widget.url,fit: BoxFit.cover,),
                          ),
                        ),
                      );
                    },
                    onPageChanged: (int page) {
                      if (page != _currentPage) {
                        // 更新tag值
                        if (mounted) {
                          setState(() {
                            _currentPage = page;
                          });
                        }
                      }
                    },
                  )),
            ),
          ),
          Positioned(
            bottom: ScreenUtil().bottomBarHeight + 30.h,
            left: 0,
            right: 0,
            child: UIRow(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                UIContainer(
                  alignment: Alignment.center,
                  padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.w),
                  radius: 5.w,
                  color: Colors.black.withOpacity(0.3),
                  child: UIText(
                    text: '${_currentPage + 1}/${widget.tags.length}',
                    textColor: Colors.white,
                    fontSize: 14.sp,
                  ),
                ),
                // if (widget.messageList?[_currentPage].original == false && widget.messageList?[_currentPage].local == null)
                //   UIText(
                //     padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.w),
                //     text: 'Download original',
                //     textColor: Colors.white,
                //     fontSize: 14.sp,
                //     radius: 5.w,
                //     color: Colors.black.withOpacity(0.3),
                //     onTap: () {
                //       RCIMIWImageMessage currentMessage = widget.messageList![_currentPage];
                //       RCIMIWMediaMessage mimeMessage = currentMessage;
                //       WhlRCIMUtils.engine.downloadMediaMessage(mimeMessage,
                //           listener: RCIMIWDownloadMediaMessageListener(onMediaMessageDownloaded: (int? code, RCIMIWMediaMessage? message) {
                //             print(message?.local ?? '');
                //           }, onMediaMessageDownloading: (RCIMIWMediaMessage? message, int? progress) {
                //             print(progress);
                //           }));
                //     },
                //   )
              ],
            ),
          ),
        ],
      ),
    );
  }

  buildImageView(index) {
    NIMMessage message = widget.messageList![index];
    Map dic = message.messageAttachment?.toMap()??{};
    String path = dic['path'] ?? '';
    String url = dic['url'] ?? '';
    return path.isNotEmpty
        ? UIImage(
            margin: EdgeInsets.only(bottom: 10.h),
            image: Image.file(File(path), fit: BoxFit.fitWidth),
            onTap: () {
              // doClickImage();
            },
          )
        : UIImage(
            margin: EdgeInsets.only(bottom: 10.h),
            httpImage: url,
            fit: BoxFit.fitWidth,
            // image: Image.memory(
            //   base64.decode(message.thumbnailBase64String?.replaceAll(RegExp(r'\s+'), '') ?? ''),
            //   fit: BoxFit.fitWidth,
            // ),
            onTap: () {
              // doClickImage();
            },
          );
  }

  void _onPanStart() {
    setState(() {
      _visible = false;
    });
  }

  void _onPanEnd() {
    setState(() {
      _visible = true;
    });
  }

  _onDoubleTap(context) {
    _isHideTitleBar = true;
    Size? size = context.size;
    _isEnlarge = !_isEnlarge;
    setState(() {
      if (!_isEnlarge) {
        _scale = 2.0;
        _offset = Offset(-(size!.width / 2), -(size!.height / 2));
      } else {
        _scale = 1.0;
        _offset = Offset.zero;
      }
    });
  }

  Offset _clampOffset(Offset offset, context) {
    final Size? size = context.size;
    // widget的屏幕宽度
    final Offset minOffset = Offset(size?.width ?? 0, size?.height ?? 0) * (1.0 - _scale);
    // 限制他的最小尺寸
    return Offset(offset.dx.clamp(minOffset.dx, 0.0), offset.dy.clamp(minOffset.dy, 0.0));
  }

  _handleOnScaleStart(ScaleStartDetails details) {
    setState(() {
      _isHideTitleBar = true;
      _previousScale = _scale;
      _normalizedOffset = (details.focalPoint - _offset) / _scale;
      // 计算图片放大后的位置
      _controller.stop();
    });
  }

  _handleOnScaleUpdate(ScaleUpdateDetails details, BuildContext context) {
    setState(() {
      _scale = (_previousScale * details.scale).clamp(1.0, 3.0);
      // 限制放大倍数 1~3倍
      _offset = _clampOffset(details.focalPoint - _normalizedOffset! * _scale, context);
      // 更新当前位置
    });
  }

  _handleOnScaleEnd(ScaleEndDetails details, BuildContext context) {
    final double magnitude = details.velocity.pixelsPerSecond.distanceSquared;
    if (magnitude < _kMinFlingVelocity) return;
    final Offset direction = details.velocity.pixelsPerSecond / magnitude;
    // 计算当前的方向
    final double distance = (Offset.zero & (context.size ?? Size.zero)).shortestSide;
    // 计算放大倍速，并相应的放大宽和高，比如原来是600*480的图片，放大后倍数为1.25倍时，宽和高是同时变化的
    _animation = _controller.drive(Tween<Offset>(begin: _offset, end: _clampOffset(_offset + direction * distance, context)));
    _controller
      ..value = 0.0
      ..fling(velocity: magnitude / 1000.0);
  }

  @override
  void dispose() {
    _pageController.dispose();
    _controller?.dispose();
    super.dispose();
  }

  Future<void> saveImageToGallery(String imageUrl) async {
    try {
      // Load the image as Uint8List using CachedNetworkImageProvider
      final provider = CachedNetworkImageProvider(imageUrl);
      final ImageStream stream = provider.resolve(ImageConfiguration.empty);
      final Completer<Uint8List> completer = Completer<Uint8List>();

      stream.addListener(ImageStreamListener((ImageInfo info, bool synchronousCall) async {
        final ByteData? imageData = await info.image.toByteData(format: ImageByteFormat.png);
        if (completer.isCompleted) {
          return;
        }
        completer.complete(imageData?.buffer.asUint8List());
      }));

      await completer.future;

      // Save the image to gallery
      final Uint8List bytes = await completer.future;
      final result = await ImageGallerySaver.saveImage(bytes);
      if (result['isSuccess']) {
        MyToast.show('Save success');
      } else {
        MyToast.show('Save failed');
      }
    } catch (e) {
      print(e);
    }
  }
}
